package other.system.client.oa.submit;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.exception.XsyHttpException;
import com.rkhd.platform.sdk.http.*;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import org.apache.commons.lang.StringUtils;
import other.system.client.apitool.OAClientUtils;
import other.system.client.util.FileServive;
import other.system.client.util.ResultBody;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Description: 提交通过方法
 * @Author: 黎炎松
 * @Date: 2024/7/9 18:09
 */
public class SubmitSuper {

    private static final Logger logger = LoggerFactory.getLogger();

    // 附件统一维护key  正式环境、测试环境一样
    public static final Map<String, String>  fileKeyMap = new HashMap<String, String>(){{
        put("quote", "fd_37b206c7ec7a50"); // 报价单
        put("contract", "fd_3a4370c9fb420c"); // 合同 fd_37b206c7ec7a50
        put("specialSontract", "fd_37b1eacec79370"); // 特殊合同
        put("bid", "fd_37b206c7ec7a50"); // 投标类文件
        put("bid2", "fd_37b206c7ec7a50"); // 投标类文件
        put("sale", "fd_37b206c7ec7a50"); // 其它销售类文件
        put("purchase", "fd_37b1eacec79370"); // 零星采购
        put("campaign", "fd_3742451808f894"); // 市场活动 （项目所属部门团队）
    }};

    /**
     * 重新提交OA审批数据 调整节点状态 自动提交
     * @return
     */
    public void resubmitApprovalData(String oaApprovalId, JSONObject ownerOaAccount) {
        String LOGGER_MSG = "重新提交OA的审批数据 ==> ";

        // 发送的数据
        JSONObject sendData = new JSONObject();
        //sendData.put("docSubject", "报价070402"); // 标题
        sendData.put("fdId", oaApprovalId); // 文档id

        // 重新提交 流程参数
        JSONObject operationData = new JSONObject();
        operationData.put("operationType", "handler_pass");
        operationData.put("auditNote", "CRM重新提交");
        String operStr = "{\"notifyLevel\":\"3\",\"notifyOnFinish\":true,\"notifyForFollow\":false,\"jumpToNodeId\":\"N2\",\"refusePassedToThisNode\":false,\"refusePassedToThisNodeOnNode\":false,\"refusePassedToTheNode\":false}";
        operationData.put("operParam", JSONObject.parseObject(operStr));
        sendData.put("flowParam", operationData);

        // 登录名、操作人
        sendData.put("docCreator", ownerOaAccount);

        // 发送数据
        logger.info( "重新提交OA请求的数据 ==> " + oaApprovalId);
        logger.info(String.valueOf(sendData));
        ResultBody resultBody = OAClientUtils.sendPost(sendData, OAClientUtils.UNDO_APPROVAL_URL, false);
        logger.info(LOGGER_MSG + "resultBody: " + resultBody);
        if (!Objects.equals(resultBody.getCode(), "200")) {
            logger.info(LOGGER_MSG + "重新提交OA发送请求异常: " + resultBody.getMessage());
        }
    }

    /**
     * 统一发送请求到OA
     * @param tempStr
     * @param title
     * @param formObject
     * @return
     */
    public ResultBody pushReqToOa(String tempStr, String title, String fdMainId, JSONObject ownerOaAccount, JSONObject formObject, JSONArray fileList) throws XsyHttpException {
        if (ownerOaAccount == null) {
            return ResultBody.error("当前数据所有人OA账号获取异常");
        }

        // 拼接需要发送的数据
        JSONObject sendData = new JSONObject();
        sendData.put("fdTemplateId", OAClientUtils.tempIdMap.get(tempStr)); // 模版id

        // 登录名、操作人
        //JSONObject docCreator = new JSONObject();
        //docCreator.put("LoginName", defaultLoginName);
        sendData.put("docCreator", ownerOaAccount);

        // id 有值则进行修改
        String sendUrl = OAClientUtils.PUSH_APPROVAL_URL;
        if (StringUtils.isNotBlank(fdMainId)) {
            logger.info( "进行更新操作");
            sendData.put("fdId", fdMainId);
            sendUrl = OAClientUtils.UP_APPROVAL_URL;
        }

        // 判断是否更新附件的值 (2024-09-24 因为附件最大5M限制,已调整为新的附件上传)
        boolean isSendFile = false;
        if (fileList != null && fileList.size() > 0) {
            // 更新附件特殊处理 1.中文进行编码  2.发送类型调整 multipart/form-data
            sendData.put("docSubject", getCodingString(title)); // 标题
            dealFileData(sendData, fileList, fileKeyMap.get(tempStr));
            isSendFile = true;
        } else {
            // 新增、更新审批数据
            sendData.put("docSubject", title); // 标题
            sendData.put("formValues", formObject); // 表单值
            logger.info( "请求的数据 ==> ");
            logger.info(String.valueOf(sendData));
        }

        // 发送数据
        ResultBody resultBody = OAClientUtils.sendPost(sendData, sendUrl, isSendFile);
        return resultBody;
    }


    /**
     * 处理文件发送的数据
     *
     * @param sendData
     * @param fileList
     * @param fdKey
     */
    public void dealFileData(JSONObject sendData, JSONArray fileList, String fdKey) throws XsyHttpException {
        for (int i = 0; i < fileList.size(); i++) {
            JSONObject fileData = (JSONObject) fileList.get(i);
            sendData.put("attachmentForms[" + i + "].fdKey", fdKey); // 附件
            sendData.put("attachmentForms[" + i + "].fdFileName", getCodingString(fileData.getString("name"))); // 附件
            //sendData.put("attachmentForms[" + i + "].fdAttachment", getRkhdBlob_new(fileData.getString("name"), fileData.getString("url"))); // 附件
            sendData.put("attachmentForms[" + i + "].fdAttachment", getRkhdBlob(fileData.getString("url"))); // 附件
        }
    }

    /**
     * 乱码问题 进行转码
     * @param str
     * @return
     */
    public static String getCodingString(String str) {
        String newStr = "";
        try {
            if (StringUtils.isNotBlank(str)) {
                newStr = new String(str.getBytes("UTF-8"), "ISO-8859-1");
            }
        } catch (UnsupportedEncodingException e) {
            logger.info("字符串转码异常 ==> " + e.getMessage());
        }
        return newStr;
    }

    /**
     * 获取文件流
     * @param downUrl
     * @return
     */
    public RkhdBlob getRkhdBlob_new(String fileName, String downUrl) {
        // 获取blob对象
        RkhdBlob rkhdBlob = new RkhdBlob();
        rkhdBlob.setBytes(FileServive.getFileByteByUrl(downUrl));
        rkhdBlob.setFileName(fileName);
        return rkhdBlob;
    }


    public RkhdBlob getRkhdBlob(String downUrl) throws XsyHttpException {
        // 系统的 downBlob 文件最大只支持5M
        CommonData data = CommonData.newBuilder()
                .callType("GET")
                .callString(downUrl)
                .build();
        RkhdBlob rkhdBlob = CommonHttpClient.instance(60000, 60000).downBlob(data);
        // 设置文件名
        if (rkhdBlob.getFileName() == null || rkhdBlob.getFileName().length() == 0) {
            // fileName 不能为空;应该包括文件名和扩展名
            String fileSuffix = getFileSuffix(downUrl);
            if (fileSuffix == null) {
                // 获取不到文件类型
                return null;
            }
            String fileName = UUID.randomUUID().toString().replace("-", "");
            fileName = fileName + "." + fileSuffix;
            rkhdBlob.setFileName(fileName);
        }
        return rkhdBlob;
    }

    /**
     * 获取文件名后缀
     *
     * @param str
     * @return
     */
    public String getFileSuffix(String str) {
        String[] splitArr = str.split("\\.");
        int length = splitArr.length;
        if (length <= 0) {
            return null;
        }
        return splitArr[length - 1];
    }


    /**
     * 获取选项的字符串值
     * @param optionArr
     * @return
     */
    public String getOptionStr(JSONArray optionArr) {
        String optStr = "";
        if (optionArr != null && optionArr.size() > 0) {
            optStr = optionArr.stream().map(v -> v.toString()).collect(Collectors.joining(","));
        }
        return optStr;
    }

    /**
     * 获取 所有人、加签节点 、的OA账号数据 首先判断用户是否有oa登录账号 否则判断邮箱是否是格创的邮箱且有值则取前缀
     * @param objectData
     * @param oaType 1：加签节点  2: 所有人 3:合同交付责任人
     * @return
     */
    public static JSONObject getOaAccount(JSONObject objectData, int oaType) {
        JSONObject nodeData = new JSONObject();

        String accountKey = "oaAccount";
        String emailKey = "oaEmail";
        switch (oaType) {
            case 1:
                accountKey = "oaAccount";
                emailKey = "oaEmail";
                break;
            case 2:
                accountKey = "ownerOaAccount";
                emailKey = "ownerOaEmail";
                break;
            case 3:
                accountKey = "zrrOaAccount";
                emailKey = "zrrOaEmail";
                break;
        }
        String oaAccount = objectData.getString(accountKey);
        String oaEmail = objectData.getString(emailKey);


        // 有OA登录账号直接返回
        if (StringUtils.isNotBlank(oaAccount)) {
            nodeData.put("LoginName", oaAccount);
            logger.info("nodeData ==> " + nodeData);
            return nodeData;
        }

        // 获取邮箱前缀 yan12.xia@getech.cn yan12.xia
        if (StringUtils.isNotBlank(oaEmail)) {
            String[] split = oaEmail.split("@");
            if (split.length > 1 && split[1].equals("getech.cn")) {
                nodeData.put("LoginName", split[0]);
                logger.info("nodeData ==> " + nodeData);
                return nodeData;
            }
        }

        return null;
    }


    /**
     * 更新对象的数据
     * @param updateData
     * @param apiKey
     * @throws Exception
     */
    public void updateObjetData(JSONObject updateData,String apiKey) throws Exception {
        logger.info("apiKey：" + apiKey);
        logger.info("需要更新的数据：" + updateData.toString());
        JSONObject params = new JSONObject();
        params.put("data", updateData);
        Long id = updateData.getLong("id");
        RkhdHttpClient httpClient = new RkhdHttpClient();
        RkhdHttpData data  = RkhdHttpData.newBuilder()
                .callType("PATCH")
                .callString("/rest/data/v2.0/xobjects/"+apiKey+"/"+id)
                .header("xsy-criteria", "10")
                .body(params.toJSONString())
                .build();
        String execute = httpClient.execute(data, e -> e);
        JSONObject result = JSONObject.parseObject(execute);
        logger.info("更新结果：" + result);
        if(result.getInteger("code") != 200){
            throw new RuntimeException(result.getString("msg"));
        }
    }

}

